Functional Interfaces এবং Generics একত্রে ব্যবহার করে কোডের ফ্লেক্সিবিলিটি এবং পুনঃব্যবহারযোগ্যতা বাড়ানো যায়। Functional Interfaces হল এক ধরনের ইন্টারফেস, যেখানে শুধুমাত্র একটি অ্যাবস্ট্রাক্ট মেথড থাকে। Generics এর মাধ্যমে Functional Interfaces টাইপ-অ্যাগনস্টিক করা যায়, যা কোডে টাইপ সেফটি এবং রিডেবিলিটি নিশ্চিত করে।
Functional Interfaces এবং Generics এর সংযোগ
- Functional Interfaces:
- একটি অ্যাবস্ট্রাক্ট মেথড নিয়ে তৈরি ইন্টারফেস।
- Lambda Expressions বা Method References এর মাধ্যমে সহজে ব্যবহার করা যায়।
- Generics:
- Functional Interfaces কে জেনেরিক টাইপের মাধ্যমে ডাইনামিক ও পুনঃব্যবহারযোগ্য করা যায়।
Common Functional Interfaces (java.util.function):
Function<T, R>: একটি ইনপুট নিয়ে একটি আউটপুট প্রদান করে।Predicate<T>: একটি শর্ত যাচাই করেbooleanআউটপুট প্রদান করে।Consumer<T>: ইনপুট গ্রহণ করে কিন্তু কিছু রিটার্ন করে না।Supplier<T>: কোনো ইনপুট ছাড়া একটি আউটপুট প্রদান করে।BiFunction<T, U, R>: দুটি ইনপুট নিয়ে একটি আউটপুট প্রদান করে।
Functional Interfaces এবং Generics এর উদাহরণ
1. Custom Generic Functional Interface
@FunctionalInterface
interface Transformer<T, R> {
R transform(T input);
}
public class Main {
public static void main(String[] args) {
// String to Integer Transformer
Transformer<String, Integer> stringToInteger = Integer::parseInt;
System.out.println("String to Integer: " + stringToInteger.transform("123"));
// Integer to Double Transformer
Transformer<Integer, Double> intToDouble = input -> input * 2.5;
System.out.println("Integer to Double: " + intToDouble.transform(10));
}
}
আউটপুট:
String to Integer: 123
Integer to Double: 25.0
উপকারিতা:
- Generics ব্যবহার করে একাধিক টাইপের জন্য একই Functional Interface ব্যবহার করা যায়।
- টাইপ সেফটি নিশ্চিত হয়।
2. Using Built-in Functional Interfaces with Generics
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
// Function to calculate square
Function<Integer, Integer> square = x -> x * x;
System.out.println("Square of 5: " + square.apply(5));
// Function to convert String to Uppercase
Function<String, String> toUpperCase = String::toUpperCase;
System.out.println("Uppercase: " + toUpperCase.apply("hello"));
}
}
আউটপুট:
Square of 5: 25
Uppercase: HELLO
উপকারিতা:
- Function<T, R> এর মাধ্যমে সহজেই ইনপুট-আউটপুট সম্পর্ক তৈরি করা যায়।
- Generics ব্যবহার করে ইনপুট এবং আউটপুটের টাইপ ডাইনামিক করা যায়।
3. Predicate Example
import java.util.function.Predicate;
public class Main {
public static void main(String[] args) {
// Predicate to check if a number is even
Predicate<Integer> isEven = x -> x % 2 == 0;
System.out.println("Is 4 even? " + isEven.test(4));
System.out.println("Is 7 even? " + isEven.test(7));
}
}
আউটপুট:
Is 4 even? true
Is 7 even? false
উপকারিতা:
- শর্ত যাচাইয়ের জন্য Predicates সহজ এবং কার্যকর।
- Generics ব্যবহার করে যেকোনো টাইপের জন্য Predicate তৈরি করা যায়।
4. Consumer Example
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
// Consumer to print a value
Consumer<String> printer = System.out::println;
printer.accept("Hello, World!");
}
}
আউটপুট:
Hello, World!
উপকারিতা:
- Generics ব্যবহার করে যেকোনো টাইপের জন্য Consumer তৈরি করা যায়।
- কোড রিডেবিলিটি এবং ক্লিন কোড মেইনটেইন করা যায়।
5. Supplier Example
import java.util.function.Supplier;
public class Main {
public static void main(String[] args) {
// Supplier to provide a default value
Supplier<String> defaultMessage = () -> "Default Message";
System.out.println(defaultMessage.get());
}
}
আউটপুট:
Default Message
উপকারিতা:
- Generics ব্যবহার করে যেকোনো টাইপের জন্য ডিফল্ট ভ্যালু সরবরাহ করা যায়।
- এটি লেট লোডিং প্যাটার্নের জন্য কার্যকর।
Complex Example: Combining Functional Interfaces
import java.util.function.Function;
import java.util.function.Predicate;
public class Main {
public static void main(String[] args) {
// Predicate to check if a number is positive
Predicate<Integer> isPositive = x -> x > 0;
// Function to calculate factorial
Function<Integer, Integer> factorial = x -> {
int result = 1;
for (int i = 1; i <= x; i++) {
result *= i;
}
return result;
};
int number = 5;
if (isPositive.test(number)) {
System.out.println("Factorial of " + number + ": " + factorial.apply(number));
} else {
System.out.println("Number must be positive!");
}
}
}
আউটপুট:
Factorial of 5: 120
উপকারিতা:
- একাধিক Functional Interfaces একত্রিত করে ডাইনামিক লজিক তৈরি করা যায়।
- কোড সহজে পরিবর্তন এবং পুনঃব্যবহারযোগ্য করা যায়।
Generics এবং Functional Interfaces এর সুবিধা
- টাইপ সেফটি: টাইপ সংক্রান্ত ত্রুটি কম্পাইল টাইমে ধরা পড়ে।
- কোড রিডেবিলিটি: Lambda Expressions এবং Method References এর মাধ্যমে কোড সংক্ষিপ্ত হয়।
- পুনঃব্যবহারযোগ্যতা: একবার তৈরি করা Functional Interface বিভিন্ন টাইপের জন্য ব্যবহার করা যায়।
- ডাইনামিক কোডিং: Generics ব্যবহার করে Functional Interfaces আরও ফ্লেক্সিবল হয়।
- মেইনটেইনেবিলিটি: Generics এবং Functional Interfaces একত্রে ব্যবহার করে কোড সহজে পরিবর্তনযোগ্য এবং পরিচালনযোগ্য হয়।
Generics এবং Functional Interfaces এর সমন্বয় বড় স্কেলের জাভা প্রজেক্টে টাইপ-সেইফ, পুনঃব্যবহারযোগ্য, এবং মেইনটেইনেবল কোড তৈরি করতে সহায়ক। এটি প্রোগ্রামের মডুলারিটি বাড়ায় এবং জাভার Functional Programming ক্ষমতাকে আরও কার্যকর করে।
Read more